﻿using System.Collections.Generic;
using TimbreRecognition.Extraction;
using TimbreRecognition.Util;

namespace TimbreRecognition.FeatureExtraction
{
    public class FeatureExtractionFacade
    {
        private const int NumberOfCoefficients = FeatureConstants.NumberOfCoeficients;

        private const int SamplesPerFrame = FeatureConstants.SamplesPerFrame;

        private const float Overlapping = FeatureConstants.Overlapping;

        private const string SoundFilePattern = "*.wav";

        private const double CrossValidationPart = 0.2;

        private const double TestPart = 0.2;

        private readonly FeatureExtractor featureExtractor;

        public FeatureExtractionFacade(string[] instruemnts)
        {
            featureExtractor = new FeatureExtractor(NumberOfCoefficients, instruemnts);
        }

        public TrainingSet ExtractForTraining(string directory)
        {
            IEnumerable<string> trainingFiles = FileUtil.GetFilesFromDirectory(directory, SoundFilePattern);

            List<Feature> trainingData = featureExtractor.Extract(trainingFiles, SamplesPerFrame, Overlapping);
            List<Feature> randomized = DataUtil.Randomize(trainingData);

            List<DataItem> dataItems = FeatureUtil.FeaturesToDataItems(randomized);

            int validationSamplesCount = (int)(dataItems.Count * CrossValidationPart);
            List<DataItem> validationData = dataItems.GetRange(0, validationSamplesCount);

            int testSamplesCount = (int)(dataItems.Count * TestPart);
            List<DataItem> testData = dataItems.GetRange(validationSamplesCount, testSamplesCount);

            List<DataItem> trainigData = dataItems.GetRange(validationSamplesCount + testSamplesCount,
                dataItems.Count - validationSamplesCount - testSamplesCount);

            TrainingSet trainingSet = new TrainingSet
            {
                TrainingData = trainigData,
                ValidationData = validationData,
                TestData = testData
            };

            return trainingSet;
        }

        public List<DataItem> ExtractForClassification(string directory)
        {
            IEnumerable<string> trainingFiles = FileUtil.GetFilesFromDirectory(directory, SoundFilePattern);

            List<Feature> trainingData = featureExtractor.Extract(trainingFiles, SamplesPerFrame, Overlapping);

            List<DataItem> dataItems = FeatureUtil.FeaturesToDataItems(trainingData);

            return dataItems;
        }

        public List<Feature> ExtractFeaturesFromFile(string fileName)
        {
            List<Feature> trainingData = featureExtractor.Extract(fileName, SamplesPerFrame, Overlapping);
            return trainingData;
        }

        public List<DataItem> ExtractFromFile(string fileName)
        {
            List<Feature> features = featureExtractor.Extract(fileName, SamplesPerFrame, Overlapping);

            List<DataItem> dataItems = FeatureUtil.FeaturesToDataItems(features);

            return dataItems;
        }

        public List<Feature> ExtractFeaturesFromDirectory(string directory)
        {
            IEnumerable<string> trainingFiles = FileUtil.GetFilesFromDirectory(directory, SoundFilePattern);
            List<Feature> trainingData = featureExtractor.Extract(trainingFiles, SamplesPerFrame, Overlapping);
            return trainingData;
        }

        public List<DataItem> ExtractFromDirectory(string directory)
        {
            IEnumerable<string> trainingFiles = FileUtil.GetFilesFromDirectory(directory, SoundFilePattern);
            List<Feature> trainingData = featureExtractor.Extract(trainingFiles, SamplesPerFrame, Overlapping);

            List<Feature> randomized = DataUtil.Randomize(trainingData);

            List<DataItem> dataItems = FeatureUtil.FeaturesToDataItems(randomized);

            return dataItems;
        } 
       
    }
}
